﻿using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.Threading;
using System.Threading.Tasks;
using WMSSystem.Web.Hubs;
using WMSSystem.YSL.Dto.SignaIR;
using WMSSystem.YSL.Interfance;

namespace WMSSystem.Web.Services
{
    /// <summary>
    /// 定时推送实时统计数据到所有客户端
    /// </summary>
    public class RealTimeStatisticsPushService : BackgroundService
    {
        private readonly IServiceProvider _serviceProvider;
        private readonly ILogger<RealTimeStatisticsPushService> _logger;
        private readonly TimeSpan _period = TimeSpan.FromSeconds(30);

        public RealTimeStatisticsPushService(
            IServiceProvider serviceProvider,
            ILogger<RealTimeStatisticsPushService> logger)
        {
            _serviceProvider = serviceProvider;
            _logger = logger;
        }

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            while (!stoppingToken.IsCancellationRequested)
            {
                try
                {
                    using var scope = _serviceProvider.CreateScope();
                    var statisticsService = scope.ServiceProvider.GetRequiredService<IRealTimeStatisticsService>();
                    var hubContext = scope.ServiceProvider.GetRequiredService<IHubContext<RealTimeStatisticsHub>>();

                    var input = new GetRealTimeStatisticsInputDto { Year = DateTime.Now.Year };
                    
                    // 确保在scope内完成所有数据库操作
                    var statistics = await statisticsService.GetRealTimeStatisticsAsync(input);
                    
                    // 在scope外发送SignalR消息
                    await hubContext.Clients.All.SendAsync("ReceiveRealTimeStatistics", statistics, cancellationToken: stoppingToken);
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "推送实时统计数据时发生错误");
                }

                await Task.Delay(_period, stoppingToken);
            }
        }
    }
}
